package ferri.lorenzo;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
//import java.io.FileOutputStream;
import java.io.InputStream;

//import java.io.FileOutputStream;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.URL;

import javazoom.jl.decoder.Bitstream;
import javazoom.jl.decoder.BitstreamException;
import javazoom.jl.decoder.Header;

//import android.media.MediaPlayer;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;

public class Servercontrol extends Thread {
	/** Called when the activity is first created. */

	private static final String TAG = "UDP_SERVER";
	private boolean isRunning = false;
	private String[] filePath = null;
	private String[] ipAddress = null;
	private String port = null;
	private int delay = 129;
	private int sizepacket;
	private String[] Titolo;
	private String[] Durata;
	private int i = 0;
	private int x;
	private boolean next = true;
	private Handler ud;
	private int num_packet = 0;
	int totdur = 0;
	boolean current = false;

	public Servercontrol() {
	}

	public Servercontrol(String[] path, String[] ip, String porta, int d,
			String[] titolo, String[] durata, Handler u) {

		if (isRunning)
			stopServer();
		ud = u;

		ipAddress = ip;
		port = porta;
		filePath = path;
		delay = d;

		isRunning = true;
		Durata = durata;
		Titolo = titolo;
	}

	public void stopServer() {
		isRunning = false;
	}

	public void run() {
		x = 0;
		if (ipAddress.length >= 1) {
			for (int i = 0; i < ipAddress.length; i++)
				changeport(ipAddress[i]);
		}
		while (isRunning && x < filePath.length) {
			Log.d(TAG, "Sending packets...");
			try {

				// Retrieve the ServerName
				InetAddress serverAddr;

				title(ipAddress, Titolo[x]);
				duration(ipAddress, Durata[x]);
				notifyMessage(Integer.parseInt(Durata[x]), Titolo[x]);
				notifyMessage((float)x);
				File file = new File(filePath[x]);

				int ms = 26;
				int sendsize = 1254;
				int mstot = 0;

				/* Create new UDP-Socket */
				DatagramSocket socket = new DatagramSocket();

				
				int j = 0;
				BufferedInputStream in = new BufferedInputStream(
						new FileInputStream(file), sendsize * 8);
				byte[] mp3SoundByteArray = new byte[sendsize];
				DatagramPacket packet = new DatagramPacket(mp3SoundByteArray,
						sendsize);
				socket.setBroadcast(true);
				InputStream inputStream = new BufferedInputStream(
						new FileInputStream(file), sendsize * 8);
				
				Bitstream bitstream = new Bitstream(inputStream);

				Header frameHeader = null;

				i = 0;

				while (i != -1 && isRunning) {

					// FrameSize = 144 * BitRate / (SampleRate + Padding)
					frameHeader = bitstream.readFrame();
					if (frameHeader == null)
						i = -1;
					if (i != -1) {
						sizepacket = frameHeader.calculate_framesize();

						ms += (int) frameHeader.ms_per_frame();
						int bitrate = frameHeader.bitrate_instant();
						int bytexms = sizepacket / 26;

						j += sizepacket;			
						// Log.d("framesize", "" + j);
						bitstream.closeFrame();
						
						if (j >= sendsize) {

							int rest = j - sendsize;		
							int msxrest = rest / bytexms;
							ms -= msxrest;
							i = in.read(mp3SoundByteArray, 0, sendsize);
							for (int y = 0; y < ipAddress.length; y++) {
								serverAddr = InetAddress
										.getByName(ipAddress[y]);
								packet = new DatagramPacket(mp3SoundByteArray,
										0, sendsize, serverAddr,
										Integer.parseInt(port));
								socket.send(packet);
							}

							
							if(bitrate>=128000)
								Thread.sleep(ms - (delay + ipAddress.length - 1));
							else
								Thread.sleep(ms - (delay + ipAddress.length));	
							
							mstot += ms;
							totdur += ms;
							if (mstot >= 2000 && current) {
								notifyMessage(totdur);
								mstot = 0;
							}

							j = rest;
							ms = msxrest;
						
							num_packet++;

							/* Send out the packet */

							Log.d(TAG, "C: Sent.");

							Log.d(TAG, "i millisecondi:" + (ms));

						}

					}

				}
				mstot = 0;
				totdur = 0;
				if (next)
					x++;
				else
					next = true;
				socket.close();
				notifyMessage("OK");

			} catch (InterruptedException e) {
				Log.d(TAG, "ERROR: " + e);
				isRunning = false;
			} catch (IOException e) {
				Log.d(TAG, "IO_ERROR: " + e);
				isRunning = false;

			} catch (BitstreamException e) {
				// TODO Auto-generated catch block
				Log.d(TAG, "IO_ERROR: " + e);
				isRunning = false;
			}
		}
		Log.d(TAG, "Server stopped!");
		notifyMessage(num_packet, "Stop");
	}

	public void next() {
		i = -1;

	}

	public void back() {

		if (x > 0) {
			next = false;
			i = -1;
			x--;
		}

	}

	private void notifyMessage(String str) {
		Message msg = ud.obtainMessage();
		Bundle b = new Bundle();
		b.putString("reset", str);
		msg.setData(b);
		ud.sendMessage(msg);
	}

	private void notifyMessage(int str, String Titolo) {
		Message msg = ud.obtainMessage();
		Bundle b = new Bundle();
		b.putInt("dur", str);
		b.putString("titolo", Titolo);
		msg.setData(b);
		ud.sendMessage(msg);
	}

	private void notifyMessage(int i) {
		Message msg = ud.obtainMessage();
		Bundle b = new Bundle();
		b.putInt("now", i);
		msg.setData(b);
		ud.sendMessage(msg);
	}


	private void notifyMessage(float i) {
		Message msg = ud.obtainMessage();
		Bundle b = new Bundle();
		b.putFloat("albart", i);
		msg.setData(b);
		ud.sendMessage(msg);
	}
	public void getdur() {

		notifyMessage(Integer.parseInt(Durata[x]), Titolo[x]);
	}

	public String[] getsongs() {
		return filePath;
	}

	public void setcurrent() {

		if (current)
			current = false;
		else
			current = true;
	}

	public void changeport(String Ip) {

		try {
			URL url = new URL("http://" + Ip + "/control.cgi?port=" + port);
			HttpURLConnection c = (HttpURLConnection) url.openConnection();
			c.setReadTimeout(1);
			c.setConnectTimeout(100);
			c.getResponseCode();
			Log.i(TAG, "http://" + ipAddress + "/control.cgi?port=" + port);

		} catch (IOException e) {
			Log.i("HTTP", "richiesta fallita");
		}

	}

	public static void title(String[] Ip, String Titolo) {
		for (int i = 0; i < Ip.length; i++) {
			try {

				URL url = new URL("http://" + Ip[i] + "/control.cgi?name="
						+ Titolo);
				HttpURLConnection c = (HttpURLConnection) url.openConnection();
				c.setReadTimeout(1);
				c.setConnectTimeout(100);
				c.getResponseCode();

				Log.i(TAG, "http://" + Ip[i] + "/control.cgi?name=" + Titolo);
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
	}

	public static void duration(String[] Ip, String Durata) {

		for (int i = 0; i < Ip.length; i++) {
			try {
				URL url = new URL("http://" + Ip[i] + "/control.cgi?during="
						+ Durata);
				HttpURLConnection c = (HttpURLConnection) url.openConnection();
				c.setReadTimeout(1);
				c.setConnectTimeout(100);
				c.getResponseCode();
				Log.i(TAG, "http://" + Ip[i] + "/control.cgi?during=" + Durata);
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
	}
}